package com.xcc.routerlib.utils;

import android.content.Context;
import android.content.Intent;
import android.os.Parcelable;
import android.text.TextUtils;

import com.google.gson.Gson;
import com.xcc.routerlib.BuildConfig;
import com.xcc.routerlib.annotation.Autowired;
import com.xcc.routerlib.annotation.RouteNode;

import org.json.JSONObject;

import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Type;

/**
 * ****************************************************
 * 作者 :: rookieCi<1056907550@qq.com>
 * ----------------------------------------------------
 * git :: https://gitee.com/rookieci
 * ----------------------------------------------------
 * 博客 :: http://blog.csdn.net/xcccicishuai
 * ----------------------------------------------------
 * 时间 :: 2019/5/28 Add by rookieCi
 * ----------------------------------------------------
 * 描述 :: ActionUtils
 * ****************************************************
 */
public class ActionUtils {
    private String action;
    private String extras;
    private Context context;
    private Intent intent;

    public ActionUtils(Context context) {
        this.context = context;
    }

    public void setAction(String action) {
        this.action = action;
    }

    public void setExtras(String extras) {
        this.extras = extras;
    }

    public Intent resolve() {
        try {
            Class aClass = Class.forName(action);
            Annotation[] annotations = aClass.getAnnotations();
            for (int i = 0; i < annotations.length; i++) {
                if (annotations[i] instanceof RouteNode) {
                    intent = new Intent(context, aClass);
                    break;
                }
            }
            if (intent != null) {
                //这部分可以更改以兼容更多数据源
                JSONObject jsonObject = new JSONObject(extras);

                Field[] fields = aClass.getDeclaredFields();
                //Field[] fields = aClass.getFields();
                for (int i = 0; i < fields.length; i++) {
                    Field field = fields[i];
                    annotations = field.getAnnotations();
                    for (int j = 0; j < annotations.length; j++) {
                        if (annotations[j] instanceof Autowired) {
                            Autowired autowired = (Autowired) annotations[j];
                            String name = field.getName();
                            Object opt = jsonObject.opt(name);
                            if (autowired.isJsonStr()) {
                                String v = MyJSON.toString(opt);
                                if (!TextUtils.isEmpty(v)) intent.putExtra(name, v);
                            } else injectSoul(field, name, opt);
                            break;
                        }
                    }
                }
            }
        } catch (Exception e) {
            if (BuildConfig.DEBUG) e.printStackTrace();
        }
        return intent;
    }

    /**
     * 注入灵魂
     */
    private void injectSoul(Field field, String name, Object opt) {
        Type genericType = field.getGenericType();
        String typeName = genericType.toString();
        if (BuildConfig.DEBUG) System.out.println(">" + genericType.toString() + "<");
        if ("boolean".equals(typeName)) {//boolean
            boolean v = MyJSON.toBoolean(opt);
            intent.putExtra(name, v);
        } else if ("byte".equals(typeName)) {//byte
            byte v = MyJSON.toByte(opt);
            intent.putExtra(name, v);
        } else if ("char".equals(typeName)) {//char
            String v = MyJSON.toString(opt);
            if (!TextUtils.isEmpty(v)) {
                char[] chars = v.toCharArray();
                if (chars.length > 0) intent.putExtra(name, chars[0]);
            }
        } else if ("short".equals(typeName)) {//short
            int vt = MyJSON.toInteger(opt);
            short v = (short) vt;
            intent.putExtra(name, v);
        } else if ("int".equals(typeName)) {//int
            int v = MyJSON.toInteger(opt);
            intent.putExtra(name, v);
        } else if ("long".equals(typeName)) {//long
            long v = MyJSON.toLong(opt);
            intent.putExtra(name, v);
        } else if ("float".equals(typeName)) {//float
            double vt = MyJSON.toDouble(opt);
            float v = (float) vt;
            intent.putExtra(name, v);
        } else if ("double".equals(typeName)) {//double
            double v = MyJSON.toDouble(opt);
            intent.putExtra(name, v);
        } else if (typeName.startsWith("class")) {
            if ("class java.lang.String".equals(typeName)) {//class String
                String v = MyJSON.toString(opt);
                if (!TextUtils.isEmpty(v)) intent.putExtra(name, v);
            } else {//class
                Class<?> typeClass = field.getType();
                Object o = new Gson().fromJson(opt.toString(), typeClass);
                //Serializable//Parcelable
                if (o instanceof Serializable)
                    intent.putExtra(name, (Serializable) o);
                else if (o instanceof Parcelable)
                    intent.putExtra(name, (Parcelable) o);
            }
        }
    }
}
